package mysocket

import (
	con "context"
	"encoding/json"
	cli "etcdview/client"
	"etcdview/key"
	"etcdview/mylog"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"go.etcd.io/etcd/clientv3"
	"strconv"
	"sync"
	"time"
)

var (
	upgrader = websocket.Upgrader{
		// 读取存储空间大小
		ReadBufferSize: 1024,
		// 写入存储空间大小
		WriteBufferSize: 1024,
	}
	l         = sync.Mutex{}
	etcdPoint string
)

func BindIP(context *gin.Context) {
	m := make(map[string]string)
	context.Bind(&m)
	etcdPoint = m["etcdPoint"]
	context.JSON(200, "ok")
}
func Init(context *gin.Context) {
	var (
		wbsCon *websocket.Conn
		err    error
	)
	m := make(map[string]string)
	if wbsCon, err = upgrader.Upgrade(context.Writer, context.Request, nil); err != nil {
		mylog.Error(err.Error())
		return // 获取连接失败直接返回
	}

	for {
		_, msg, err := wbsCon.ReadMessage()
		if err != nil {
			mylog.Error(err.Error())
			// 关闭连接
			wbsCon.Close()
		}
		if string(msg) == "init" {
			key.KeysMap = make(map[int][]key.SingleKey)
			key.KeysMap[-1] = key.TopKey
			client, err := clientv3.New(clientv3.Config{
				Endpoints:   []string{etcdPoint},
				DialTimeout: time.Second,
			})
			if err != nil {
				m["code"] = "500"
				m["msg"] = "输入ip有误，无法建立连接"
				sendMsg(wbsCon, m)
				m = make(map[string]string)
				continue
			}
			cli.Client = client
			mylog.Println("连接ETCD：【" + etcdPoint + "】成功！")

			ctx, cancelFunc := con.WithCancel(con.Background())
			get, err := client.Get(ctx, "/", clientv3.WithFromKey())
			if err != nil {
				mylog.Error(err.Error())
				m["code"] = "500"
				m["msg"] = "初始化数据有误，请检查ip是否正确"
				sendMsg(wbsCon, m)
				m = make(map[string]string)
				continue
			}
			for i, kv := range get.Kvs {
				key.RegisterSingleKey(string(kv.Key))
				m["msg"] = string(kv.Key) + " 初始化完毕！"
				m["percent"] = strconv.Itoa(((i + 1) * 100) / len(get.Kvs))
				sendMsg(wbsCon, m)
			}
			m["msg"] = "所有key初始化完毕！"
			m["percent"] = strconv.Itoa(100)
			sendMsg(wbsCon, m)
			mylog.Info("所有key初始化完毕！")
			m = make(map[string]string)
			cancelFunc()
		}
	}

}

func sendMsg(wbsCon *websocket.Conn, m map[string]string) {
	if marshal, err := json.Marshal(m); err == nil {
		if err := wbsCon.WriteMessage(websocket.TextMessage, marshal); err != nil {
			mylog.Error(err.Error())
			// 关闭连接
			wbsCon.Close()
		}
	}

}

func GetCols(context *gin.Context) {
	k := key.Key{
		Id:       key.KeysMap[-1][0].SKeyId,
		Label:    key.KeysMap[-1][0].Name,
		Path:     key.KeysMap[-1][0].Path,
		Children: getChildren(-1, 0, key.KeysMap[-1][0].SKeyId),
	}
	context.JSON(200, k)
}

func getChildren(i int, no int, id int) []key.Key {
	var keys []key.Key
	singleKey := key.KeysMap[i][no]
	for no1, sk := range key.KeysMap[i+1] {
		if sk.FSKeyId == singleKey.SKeyId {
			children := getChildren(i+1, no1, sk.SKeyId)
			k := key.Key{
				Id:       sk.SKeyId,
				Label:    sk.Name,
				Path:     sk.Path,
				Children: children,
			}
			keys = append(keys, k)
		}
	}
	return keys
}
